package com.ky.user.service.impl;

import cn.hutool.core.convert.NumberWithFormat;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.ky.common.config.RedisKeyConfig;
import com.ky.common.config.SystemConfig;
import com.ky.common.param.UserAdd;
import com.ky.common.param.UserLogin;
import com.ky.common.vo.R;
import com.ky.user.entity.User;
import com.ky.common.util.JwtUtil;


import com.ky.user.mapper.UserMapper;
import com.ky.user.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;


import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

import java.util.Set;
import java.util.concurrent.TimeUnit;



/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author wgz
 * @since 2024-06-17
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 使用用户名密码登录
     * @param userLogin
     * @return
     */
    @Override
    public R loginPass(UserLogin userLogin) {
        // 1.判断参数是否为空
        if (userLogin == null || StringUtils.isAnyEmpty(userLogin.getName(), userLogin.getPass())) {
            return R.fail("参数为空");
        }
        // 2.判断账户是存在，可用
        String username = userLogin.getName();
        String password = userLogin.getPass();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        List<User> userList = userMapper.selectList(queryWrapper);
        if (userList == null || userList.size() <= 0) {
            return R.fail("用户不存在");
        }
        // 3.判断登录次数是否超过三次
        User user = userList.get(0);
        Set<String> keys = redisTemplate.keys(RedisKeyConfig.LOGIN_UID_TOKEN + user.getId() + "*");
        if (keys != null && keys.size() >= 3) {
            return R.fail("登录次数超过三次");
        }
        // 4.验证用户密码
        if (!user.getPassword().equals(SecureUtil.md5(password))) {
            return R.fail("密码错误");
        }
        // 5.生成token
        String token = JwtUtil.createJwt(user.getId(), username, user.getPhone());
        // 6.存储token
        //  key   id + token       可以计算该id登录的次数  ==》  key:lc:uid:用户id:令牌   value 时间戳
        //  key   token         记录该token 对应的用户信息 ====> key:lc:token:令牌     value 用户对象信息
        stringRedisTemplate.opsForValue().set(RedisKeyConfig.LOGIN_UID_TOKEN + user.getId() + ":" + token, "", 12 * 60 * 60, TimeUnit.SECONDS);
        redisTemplate.opsForValue().set(RedisKeyConfig.LOGIN_TOKEN + token, user, 12 * 60 * 60, TimeUnit.SECONDS);
        //redis中设置一个今日单词数量，时间为24小时，初始值为0
        //判断redis是否存在

        if (redisTemplate.hasKey("todayWordNum" + user.getId())) {
            //存在，直接返回
            return R.ok(token);
        }
        redisTemplate.opsForValue().set("todayWordNum" + user.getId(), 0, 24 * 60 * 60, TimeUnit.SECONDS);
        //创建一个List类型的redis
        if (!redisTemplate.hasKey("wordList" + user.getId())){
        redisTemplate.opsForList().leftPush("wordList"+ user.getId(), "");
        }
        // 8.返回token
        return R.ok(token);
    }

    /**
     * 使用验证码登录
     * @param userLogin
     * @return
     */
    @Override
    public R loginCode(UserLogin userLogin) {
        // 1.判断参数是否为空
        if (userLogin == null || StringUtils.isAnyEmpty(userLogin.getName(), userLogin.getPass())) {
            return R.fail("参数为空");
        }
        //判断手机号是否存在  是否可用
        String phone = userLogin.getName();
        String code = userLogin.getPass();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        List<User> users = userMapper.selectList(queryWrapper);
        if (users == null || users.size() <= 0) {
            return R.fail("手机号不存在");
        }
        //判断当前手机号的在线次数是否超过 三次
        User user = users.get(0);
        Set<String> keys = redisTemplate.keys(RedisKeyConfig.LOGIN_UID_TOKEN + user.getId() + "*");
        if (keys == null && keys.size() > 3) {
            return R.fail("登录次数超过三次");
        }
        // 验证手机号验证码
        String loginCode = stringRedisTemplate.opsForValue().get(RedisKeyConfig.SMS_LCODE + phone);
        if (!code.equals(loginCode)) {
            return R.fail("验证码错误");
        }
        // 生成token
        String token = JwtUtil.createJwt(user.getId(), phone, user.getPhone());
        // 6.存储token
        //  key   id + token       可以计算该id登录的次数  ==》  key:lc:uid:用户id:令牌   value 时间戳
        //  key   token         记录该token 对应的用户信息 ====> key:lc:token:令牌     value 用户对象信息
        stringRedisTemplate.opsForValue().set(RedisKeyConfig.LOGIN_UID_TOKEN + user.getId() + ":" + token, "", 12 * 60 * 60, TimeUnit.SECONDS);
        redisTemplate.opsForValue().set(RedisKeyConfig.LOGIN_TOKEN + token, user, 12 * 60 * 60, TimeUnit.SECONDS);
        return R.ok(token);
    }



    /**
     * 注册
     * @param request
     * @param userAdd
     * @return
     */
    @Override
    public R register(HttpServletRequest request, UserAdd userAdd) {


        //1 判断参数是否为空
        //任何一个参数为空,返回true
        if(userAdd ==null || StringUtils.isAnyEmpty(userAdd.getAccount(),userAdd.getCode(),userAdd.getPhone(),userAdd.getPassword())){
            return R.fail("参数错误");
        }

        //2 判断验证吗是否匹配
        String redisCode = stringRedisTemplate.opsForValue().get(RedisKeyConfig.SMS_RCODE + userAdd.getPhone());
        if (!userAdd.getCode().equals(redisCode)){
            return R.fail("验证码错误");
        }

        // 3 判断手机号是否重复

        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();

        userQueryWrapper.eq("phone",userAdd.getPhone());

        List<User> users = userMapper.selectList(userQueryWrapper);
        if (users!=null &&!users.isEmpty()){
            return R.fail("手机号已被注册");
        }

        // 4 密码加密  插入user表
        User user = new User();
        user.setPhone(userAdd.getPhone())
                .setUsername(userAdd.getAccount())

                .setPassword(SecureUtil.md5(userAdd.getPassword()))
                .setCtime(new Date());

        int num = userMapper.insert(user);
        if(num<=0){
            return R.fail("注册失败");
        }
//
//        Log log = new Log();
//
//        log.setCtime(new Date())
//                .setMobile(user.getPhone())
//                .setType("用户注册")
//                .setIp(request.getRemoteHost())
//                .setInfo(user.getPhone()+"用户注册")
//                .setUserId(user.getId());
//
//        logMapper.insert(log);
//
//        MqMsg mqMsg = new MqMsg();
//        mqMsg.setType(5);;
//        GrowthAdd growthAdd = new GrowthAdd();
//        growthAdd.setGrowth(50);
//        growthAdd.setUid(user.getId());
//        growthAdd.setType("新用户注册");
//        mqMsg.setMsg(growthAdd);
//
//
//        rabbitTemplate.convertAndSend("", RabbitKeyConfig.Q_USER_GROWTH,mqMsg);






        return R.ok("注册成功");
    }

    @Override
    public User selectUser(int userId) {
        return userMapper.selectById(userId);
    }

    @Override
    public R logout(String token) {
        User user = (User) redisTemplate.opsForValue().get(RedisKeyConfig.LOGIN_TOKEN + token);
        redisTemplate.delete(RedisKeyConfig.LOGIN_TOKEN + token);
        redisTemplate.delete(RedisKeyConfig.LOGIN_UID_TOKEN + user.getId() + ":" + token);
        return R.ok("退出成功");
    }
    @Override
    public R findAllFollows() {
        List<User> selectList = userMapper.selectList(null);
        return R.ok(selectList);
    }

    @Override
    public R findByMapFollows(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("username",username);
        List<User> userList = userMapper.selectList(queryWrapper);
        return R.ok(userList);
    }

    @Override
    public R findById(Integer id) {
        User user = userMapper.selectById(id);
        return R.ok(user);
    }

    @Override
    public R saveUser(@RequestBody User user,HttpServletRequest request) {
        System.out.println(user);
        String token = request.getHeader(SystemConfig.HEADER_TOKEN);
        Integer id = ((NumberWithFormat) JwtUtil.parseToken(token, "id")).intValue();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",id);
       /* User user1 = userMapper.selectOne(queryWrapper);
        user.setUsername(user1.getUsername());*/
        int i = userMapper.update(user, queryWrapper);
        if (i>0){
            return R.ok();
        }
        return R.fail("修改失败");
    }

    @Override
    public R updatePassword(User user,HttpServletRequest request) {
        user.setPassword(SecureUtil.md5(user.getPassword()));
        return update(user,request);
    }
    @Override
    public R updatePhone(User user, HttpServletRequest request) {
        return update(user,request);
    }
    public R update(User user, HttpServletRequest request){
        String token = request.getHeader(SystemConfig.HEADER_TOKEN);
        Integer id = ((NumberWithFormat) JwtUtil.parseToken(token, "id")).intValue();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",id);
        int i = userMapper.update(user, queryWrapper);
        if (i>0){
            return R.ok();
        }
        return R.fail("修改失败");
    }
}
